package main

import "fmt"

func main() {

	// 无参无返回值函数的调用
	MyFunc()

	// 有参无返回值函数的调用
	MyFunc01(111) // 参数传递只能是实参传递给形参, 不可以相反, 单向传递

	MyFun02(12, 14)

	MyFun03(11, 16)

	test01(18, 20)

	test02()
	test02(1)
	test02(1, 2, 3)

	// 不定参数传递
	test04(1, 2, 3, 4)

	fmt.Println("无参, 只有一个返回值的函数")
	var a int
	a = testy06()
	fmt.Println("a = ", a)

	b := test07()
	fmt.Println("b = ", b)

	c := test08()
	fmt.Println("c = ", c)

	fmt.Println("函数有多个返回值")
	a, b, c = test09()
	fmt.Printf("a = %d, b = %d, c = %d", a, b, c)

	fmt.Println("\n函数有多个返回值2")
	a, b, c = test10()
	fmt.Printf("a = %d, b = %d, c = %d", a, b, c)

	fmt.Println("\n函数有多个返回值3")
	a, b, c = test11()
	fmt.Printf("a = %d, b = %d, c = %d", a, b, c)

	fmt.Println("\n函数有参数有返回值")
	max, min := MaxAndMin(10, 20)
	fmt.Printf("max = %d, min = %d\n", max, min)

	fmt.Println("\n函数有参数有返回值2")
	// 通过匿名变量丢弃某个返回值
	a, _ = MaxAndMin(10, 20)
	fmt.Printf("a = %d", a)

}

// 无参无返回值函数的定义
func MyFunc() {
	a := 666
	fmt.Println("a = ", a)
}


// 有参无返回值函数的定义, 普通参数列表
func MyFunc01(a int) {
	fmt.Println(a)
}

func MyFun02(a int, b int)  {
	fmt.Printf("a = %d, b = %d\n", a, b)
}

func MyFun03(a, b int)  {
	fmt.Printf("a = %d, b = %d\n", a, b)
}

func MyFun04(a int, b string, c float64)  {
	fmt.Printf("a = %d, b = %d\n, c = %f", a, b, c)
}

func MyFun05(a, b string, c float64, d, e int) {

}

func MyFun06(a string, b string, c float64, d int, e int) {

}


// 不定参数类型
func test01(a int, b int)  {
	
}

// 传递的参数可以是 0个或多个
func test02(args ...int)  {
	fmt.Println(len(args))
	fmt.Println("for---------------")
	for i := 0; i < len(args); i++ {
		fmt.Printf("args[i] = %d\n", args[i])
	}
	fmt.Println("range................")
	for i, data := range args{
		fmt.Printf("args[%d] = %d\n", i, data)
	}
}

// 固定参数在调用的时候一定要传参, 不定参数根据需求传递, 不定参数一定只能放在形参中的最后一个参数
func test03(a int, args ...int) {

}


// 不定参数传递
func test04(args ...int) {
	// 全部元素传递给 test05
	fmt.Println("全部元素传递给 test05")
	test05(args...)

	// 只想把后2个参数传递给另外一个函数使用
	fmt.Println("只想把前2个参数传递给另外一个函数使用")
	test05(args[:2]...) // 从 args[0] 开始, 不包括 args[2], 把前边所有的元素传递
	fmt.Println("只想把后2个参数传递给另外一个函数使用")
	test05(args[2:]...) // 从 args[2] 开始, 包括自身, 把后边所有的元素传递
}

func test05(temp ...int) {
	for _, data := range temp {
		fmt.Println("temp = ", data)
	}
}

// 无参, 只有一个返回值的函数
func testy06() int {
	return 666
}


// 给返回值起一个变量名
func test07() (result int) {
	result = 999
	return 888
}

// 给返回值起一个变量名
func test08() (result int) {
	result = 999
	return
}


// 函数有多个返回值
func test09() (int, int, int) {
	return 1, 2, 3
}

// 函数有多个返回值2
func test10() (a int, b int, c int) {
	a, b, c = 111, 222, 333
	return
}

// 函数有多个返回值2
func test11() (a, b, c int) {
	a, b, c = 444, 555, 666
	return
}

// 有参有返回值
func MaxAndMin(a, b int) (max, min int) {
	if a > b {
		max = a
		min = b
	} else {
		max = b
		min = a
	}
	return
}


